پروژه پایانی درس سیگنال ها و سیستم ها

تغییر صدا

در این پروژه به پیاده سازی سیستم زمان گسسته برای تغییر صدا پرداخته میشود از کاربردهای تبدیل صدا و تغییر پیچ صدا میتوان به نرم افزارهای متن به گفتار و تشخیص و اهراز هویت صدا اشخاص و همچنین تغییر صدا برای مجهول ماندن گوینده آن اشاره کرد

In [1]:
from scipy.io import wavfile as wav
from scipy.fftpack import fft
from pydub import AudioSegment
from pydub.playback import play
from playsound import playsound
from scipy.io.wavfile import write
import pyaudio
import wave
import numpy as np
import scipy.signal as sp
import IPython
import matplotlib.pyplot as plt
/usr/local/lib/python3.7/site-packages/pydub/utils.py:165: RuntimeWarning: Couldn't find ffmpeg or avconv - defaulting to ffmpeg, but may not work
  warn("Couldn't find ffmpeg or avconv - defaulting to ffmpeg, but may not work", RuntimeWarning)
/usr/local/lib/python3.7/site-packages/pydub/utils.py:179: RuntimeWarning: Couldn't find ffplay or avplay - defaulting to ffplay, but may not work
  warn("Couldn't find ffplay or avplay - defaulting to ffplay, but may not work", RuntimeWarning)

یک تابع پیاده سازی می کنیم، جهت رسم تبدیل فوریه ی سیگنال

In [9]:
def draw(voice):
    voice_fft = fft(voice)
    voice_fft = voice_fft[0:len(voice_fft)//2]
    plt.plot(voice_fft)

کانفیگ های ضبط صدا در سکشن زیر آمده است

In [10]:
FORMAT = pyaudio.paInt16  # format of sampling 16 bit int
CHANNELS = 1  # number of channels it means number of sample in every sampling
RATE = 44100  # number of sample in 1 second sampling
CHUNK = 1024  # length of every chunk
RECORD_SECONDS = 10  # time of recording in seconds
WAVE_OUTPUT_FILENAME = "file.wav"  # file name

با استفاده از ماژول (پای آدیو) یک استریم می سازیم و به اندازه ی یک چانک از آن بافر میکنیم و آن را در فریم ذخیره می کنیم

سپس آن فریم را در فایل ویو ذخیره می کنیم

In [11]:
audio = pyaudio.PyAudio()


print("recording...")
stream = audio.open(
    format=FORMAT,
    channels=CHANNELS,
    rate=RATE,
    input=True,
    frames_per_buffer=CHUNK
)
# start Recording

frames = []
for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
    data = stream.read(CHUNK)
    frames.append(data)

# stop Recording
stream.stop_stream()
stream.close()

# storing voice
waveFile = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
waveFile.setnchannels(CHANNELS)
waveFile.setsampwidth(audio.get_sample_size(FORMAT))
waveFile.setframerate(RATE)
waveFile.writeframes(b''.join(frames))
waveFile.close()
print('finish.')
recording...
finish.

حالت ساده

فایل ویو ضبط شده را بخش می کند

In [12]:
# reading voice
rate, data = wav.read('file.wav')
print('sampling rate : ', rate)
IPython.display.Audio(data, rate=rate)
sampling rate :  44100
Out[12]:

با استفاده از تابع (دراو) تبدیل فوریه ی صوت ضبط شده را رسم می کنیم

In [13]:
draw(data)

بدلیل اینکه بتوانیم سیستم را بصورت ریل-تایم نیز پیاده سازی کنیم، بجای شیفت در حوزه ی فرکانس و گرفتن تبدیل فوریه معکوس (که نیازمند داشتن تمام سیگنال می باشد) از ضرب در تابع اویلری در سیگنال در حوزه ی زمان استفاده می کنیم. که با توجه به حقیقی بودن سیگنال تابع اویلی برابر با همان تابع کسینوس می شود $$ y[n] = x[n] \, \cos(\omega_0 n) $$ که نتیجتا موجب شیفت یافتن سیگنال در حوزه ی فرکانس می شود و باعث می شود صدا بم تر یا زیر تر شود.

In [14]:
w =  2 * np.pi * 400 / rate
out = data * np.cos(w * np.arange(0,len(data)))

IPython.display.Audio(out, rate=rate)
Out[14]:

سیگنال جدید (شیفت یافته) را رسم میکنیم و میبینیم که شیفت یافته است

In [15]:
draw(out)

مشابه قبل با مقادیر دیگری نیز شیفت می دهیم و میبینیم که صدا هربار مجددا متفاوت می شود

In [16]:
w =  2 * np.pi * 700 / rate
out = data * np.cos(w * np.arange(0,len(data)))

IPython.display.Audio(out, rate=rate)
Out[16]:
In [17]:
draw(out)
In [18]:
w =  2 * np.pi * 900 / rate
out = data * np.cos(w * np.arange(0,len(data)))

IPython.display.Audio(out, rate=rate)
Out[18]:
In [19]:
draw(out)
In [42]:
RECORD_SECONDS_realtime = 3  # time of recording in seconds
CHUNK = 1024 # length of every chunk
WAVE_OUTPUT_FILENAME_realtime = "file_realtim.wav"  # file name

# real time is disabled because it doesn't get out of this loop unless with a keyboard interrupt
# and it generates an error showing that interupt
# if you want to run the realtime change the condition of while to "True" in the snippet below


while False:
    stream = audio.open(
        format=FORMAT,
        channels=CHANNELS,
        rate=RATE,
        input=True,
        frames_per_buffer=CHUNK
    )

    # start Recording

    frames = []
    print("recording...")
    for i in range(0, int(RATE / CHUNK * RECORD_SECONDS_realtime)):
        

        data_realtime = stream.read(CHUNK)
        
        frames.append(data_realtime)
    print("play...")


    # stop Recording
    stream.stop_stream()
    stream.close()

    # storing voice
    waveFile = wave.open(WAVE_OUTPUT_FILENAME_realtime, 'wb')
    waveFile.setnchannels(CHANNELS)
    waveFile.setsampwidth(audio.get_sample_size(FORMAT))
    waveFile.setframerate(RATE)
    waveFile.writeframes(b''.join(frames))
    waveFile.close()
    
    
    rate_realtime, data_realtime = wav.read('file_realtim.wav')
    wreal =  2 * np.pi * 400 / rate_realtime
    outreal = data_realtime * np.cos(wreal * np.arange(0,len(data_realtime)))
    write('out_realtime.wav', 44100, outreal)
    playsound('out_realtime.wav')

حالت پیشرفته

برای تغییر یک صدا به صدای دیگر لازم است که پیچ های دو سیگنال را باهم جابجا کنیم (پیچ سیگنال هدف را به جای پیچ سیگنال اولیه قرار می دهیم) که برای این کار نیاز به یک تابع برای یافتن پیچ ها و یک تابع برای تغییر پیچ ها داریم. برای این کار ابتدا پیچ های هر دو صدا را می یابیم و سپس پیچ سیگنال اولیه را به اندازه ی اختلاف پیچش با پیچ سیگنال هدف شیفت می دهیم

پیچ درواقع درک انسان از زیر و بمی صداست که با فرکانس متفاوت است و به همین دلیل است که با تغییر فرکانس خالی لزوما صدا تبدیل به صدای هدف نمی شود

پیچ تابعی از فرکانس و تراز صدا می باشد

درواقع آوا ها و صدا ها و نت های موسیقی که گوش انسان آن ها را تشخیص می دهد دارای یک ساختار متناوب (پریودیک) در حوزه ی فرکانس می باشند

برای تغییر پیچ ها این کار را در حوزه ی فرکانسی انجام میدهیم

برای تابع شیفت پیچ از الگوریتم (دی اف تی)‌استفاده مینماییم

بر روی تبدیل فوریه ی سیگنال از چپ به راست، اولین پیک را پیک اساسی (فاندیمنتال) می نامیم و بقیه را پیک های جزیی (پارشیال) می نامیم

این کار را در واقع بر روی هر نت یا آوا جداگانه انجام می دهیم

سپس هر کدام را جداگانه پیچ می دهیم و حاصل آن ها می شود صدای پیچ یافته

برای گرفتن این آواها از یک صوت، آن را به قسمت های کوچک تقسیم می کنیم که این قسمت ها باید به شکلی باشند که نه آنقدر کوچک باشند که آوا ناقص شود و تبدیل فوریه ی ما خراب شود و نه آنقدر بزرگ باشند که بیش از یک آوا ضبط شود که اصولا بین ۵۰ تا ۱۰۰ میلی ثانیه می باشد

اگر مشابه روش قبل عمل کرده و صرفا فرکانس ها را جابجا کنیم بدلیل بهم ریختن هارمونی سیگنال صدا حالت غیر واقعی پیدا می کند ( چرا که آوا های ایجاد شده توسط انسان و ساز ها همگی هارمونیک هستند) اما در این روش چون ابتدا آوا ها را از هم جدا می کنیم و هرکدام را جداگانه پیچ می کنیم حالت هارمونیک آن ها حفظ می شود و صدا حالت واقعی پیدا می کند

سیگنال صوتی صحبت انسان هارمونیک نیست بهمین دلیل سیگنال صوتی انسان را بخش بخش می کنیم (روی آن پنجره گذاری می کنیم) تا آوا ها که هارمونیک هستند را بدست بیاوریم

برای درست پیچ کردن باید هر سگمنت از سیگنال را در حوزه ی فرکانس در امتداد محور فرکانس به اندازه ی بازه ی سیگنال اصلی گسترش دهیم تا پس از تغییر پیچ همچنان هارمونیک باقی بماند

In [22]:
def DFT_rescale(x, f):
    X = np.fft.fft(x)
    # separate even and odd lengths
    parity = (len(X) % 2 == 0)
    N = int(len(X) / 2) + 1 if parity else (len(X) + 1) / 2
    Y = np.zeros(N, dtype=np.complex)
    # work only in the first half of the DFT vector since input is real
    for n in range(0, N):
        # accumulate original frequency bins into rescaled bins
        ix = int(n * f)
        if ix < N:
            Y[ix] += X[n]
    # now rebuild a Hermitian-symmetric DFT
    Y = np.r_[Y, np.conj(Y[-2:0:-1])] if parity else np.r_[Y, np.conj(Y[-1:0:-1])]
    return np.real(np.fft.ifft(Y))
In [23]:
# converting milliseconds to samples
def ms2smp(ms, Fs):
    return int(float(Fs) * float(ms) / 1000.0)
In [24]:
# trapezoid window
def win_taper(N, a):
    R = int(N * a / 2)
    r = np.arange(0, R) / float(R)
    win = np.r_[r, np.ones(N - 2*R), r[::-1]]
    stride = N - R - 1
    return win, stride

حال پنجره هایی بر روی سیگنال تعریف می کنیم با استفاده از توابع بالا

حالا بر روی تمامی این پنجره ها تابع ری-اسکیل را فراخوانی می کنیم و آن ها را گسترش می دهیم و با در نظر گرفتن مقدار معینی به عنوان اور-لپ آن ها را با هم جمع می کنیم که سیگنال حاصل ما را نتیجه می دهند

دلیل این اور-لپ این است که پیوستگی بین آوا ها را پوشش دهیم

In [25]:
def DFT_pshift(x, f, G, overlap=0):
    N = len(x)
#     IPython.display.Audio(DFT_rescale(y, 1.4), rate=Fs_y)
    y = np.zeros(N)
    win, stride = win_taper(G, overlap)
    for n in range(0, len(x) - G, stride):
        w = DFT_rescale(x[n:n+G] * win, f)
        y[n:n+G] += w * win
    return y

نتیجه ی پیچ شده ی فایل صوتی توسط مکانیزم بالا را با دو مقدار متفاوت امتحان می کنیم

  • در فرکانس های بالا تر بدلیل گسترده تر بودن سیگنال در حوزه فرکانس از اور-لپ بیشتر استفاده می کنیم
In [26]:
IPython.display.Audio(DFT_pshift(data, 1.5, ms2smp(40, rate), 0.4), rate=rate)
Out[26]:
In [27]:
IPython.display.Audio(DFT_pshift(data, 0.6, ms2smp(40, rate), 0.2), rate=rate)
Out[27]:

حال فایل صوتی هدف را ضبط می کنیم

In [28]:
WAVE_OUTPUT_FILENAME_TARGET = "fileTarget.wav"  # file name
audio = pyaudio.PyAudio()


print("recording...")
stream = audio.open(
    format=FORMAT,
    channels=CHANNELS,
    rate=RATE,
    input=True,
    frames_per_buffer=CHUNK
)
# start Recording

frames = []
for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
    dataTarget = stream.read(CHUNK)
    frames.append(dataTarget)

# stop Recording
stream.stop_stream()
stream.close()

# storing voice
waveFile = wave.open(WAVE_OUTPUT_FILENAME_TARGET, 'wb')
waveFile.setnchannels(CHANNELS)
waveFile.setsampwidth(audio.get_sample_size(FORMAT))
waveFile.setframerate(RATE)
waveFile.writeframes(b''.join(frames))
waveFile.close()
print('finish.')
recording...
finish.

صوت هدف

In [29]:
# reading target voice
rateTarget, dataTarget = wav.read('fileTarget.wav')
print('sampling rate : ', rateTarget)
IPython.display.Audio(dataTarget, rate=rateTarget)
sampling rate :  44100
Out[29]:

صوت مبدا

In [30]:
IPython.display.Audio(data, rate=rate)
Out[30]:

با استفاده الگوریتم (وای ای ای پی تی) پیچ هر دو صوت را محاسبه میکنیم و میانگین پیچ آن ها را محاسبه می کنیم

In [31]:
import amfm_decompy.basic_tools as basic
import amfm_decompy.pYAAPT as pYAAPT

def YAAPT(Fn):
    # load audio
    signal = basic.SignalObj(Fn)
    filename = Fn
    # YAAPT pitches
    pitchY = pYAAPT.yaapt(signal, frame_length=40,
                      tda_frame_length=40, f0_min=75, f0_max=600)

#     print(pitchY.samp_values)

    # plot

    fig = plt.subplots(1, 1, sharex=True, sharey=True, figsize=(12, 8))
    plt.plot(pitchY.samp_values, label='YAAPT', color='blue')
    # plt.savefig('YAAPT.png')
    plt.show()
    return pitchY.samp_values
In [37]:
file_pitch = YAAPT('file.wav')
print('pitch: ',file_pitch)
pitch:  [  0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.         177.82258065 179.26829268
 180.         180.73770492 180.73770492 180.73770492 180.73770492
 180.73770492 180.73770492 180.73770492 178.54251012 178.54251012
 177.82258065 164.55223881 163.94052045 123.52941176 135.27607362
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.         158.63309353
 158.63309353 158.63309353 156.38297872 155.28169014 109.4292804
 155.28169014 152.06896552 151.54639175 152.06896552 152.06896552
 152.06896552 152.59515571 154.1958042  156.38297872 155.83038869
 155.83038869 155.83038869 155.83038869 155.83038869 155.83038869
 155.83038869 155.83038869 155.83038869 156.38297872 156.38297872
 156.38297872 155.83038869 155.83038869 155.83038869 165.16853933
 168.32061069 172.94117647 172.94117647 172.94117647 172.94117647
 170.27027027 167.68060837 166.41509434   0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
 114.54545455 114.54545455 113.65979381 113.65979381 141.80064309
 150.         150.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.         177.82258065 177.82258065
 178.54251012 179.26829268 179.26829268 179.26829268 179.26829268
 179.26829268 179.26829268 179.26829268 178.54251012 178.54251012
 177.10843373 177.10843373 177.10843373 176.4        175.
 175.         158.06451613 157.5        157.5        157.5
 156.93950178 156.38297872 156.38297872 156.38297872 155.83038869
 155.83038869 155.83038869 156.38297872 155.83038869 155.83038869
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.         162.13235294 162.13235294 160.94890511 161.53846154
 161.53846154 162.13235294 161.53846154 162.13235294 162.13235294
 162.13235294   0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
 135.27607362 135.69230769 136.53250774 135.27607362 137.8125
 139.11671924 136.53250774 134.45121951 134.45121951 132.03592814
 122.84122563 132.78808594 122.84122563 122.84122563 130.08849558
 129.19921875 130.08849558 131.64179104 131.64179104 131.64179104
 131.64179104 131.64179104 131.64179104 131.64179104 168.96551724
 168.96551724 172.265625   154.1958042  155.28169014 172.265625
 172.265625   173.62204724 159.20577617 161.53846154 161.53846154
 161.53846154 161.53846154 161.53846154   0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.         151.54639175 151.54639175
 151.54639175 151.54639175 151.54639175 151.54639175 151.54639175
 151.54639175 151.54639175 151.54639175 151.54639175 151.02739726
 151.02739726 151.02739726 151.02739726 151.54639175 151.54639175
   0.           0.           0.           0.          91.30434783
  91.30434783  91.30434783  91.30434783  91.30434783  91.30434783
  91.30434783  90.92783505  90.74074074  90.74074074  90.92783505
  90.74074074  90.74074074  90.92783505  86.1328125  105.75539568
 103.27868852 103.03738318 102.7972028  102.08333333 101.37931034
 101.37931034 100.68493151   0.           0.           0.
   0.           0.           0.           0.         105.25059666
 105.25059666 104.75059382 103.52112676 102.7972028  101.84757506
  99.1011236   98.65771812  95.86956522  94.23076923  92.45283019
  90.18404908  88.55421687  88.55421687  86.47058824  85.13513514
  85.13513514  85.13513514 124.57627119 149.49152542 153.65853659
 156.38297872 157.5        153.65853659 154.1958042  155.83038869
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.         172.265625   172.265625   172.265625
 172.265625   177.82258065 180.         175.85449219 122.84122563
 120.82191781 122.84122563 136.37695312  94.43254818  94.23076923
  94.23076923  94.23076923  94.23076923  91.51611328  95.45454545
  95.86956522  96.07843137  96.28820961   0.           0.
   0.           0.         193.42105263 193.42105263 193.42105263
 191.73913043 190.90909091 189.27038627 187.65957447 186.07594937
 185.29411765 184.51882845 184.51882845 182.23140496 180.
 179.26829268 178.54251012 124.71313477  86.64047151  86.64047151
  86.64047151  86.64047151  86.64047151  86.64047151  86.64047151
  86.30136986  83.96858009  92.04353126 119.51219512 119.51219512
 119.51219512 120.49180328 121.48760331 121.48760331 183.75
 185.29411765 183.75         0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.         101.61290323 123.81591797
 123.81591797 121.12426758 106.76879883  92.41333008   0.
  95.24838013  95.24838013  95.24838013  95.24838013  95.24838013
  95.04310345  95.04310345  95.04310345  82.54394531   0.
   0.           0.         102.08333333 102.7972028  101.84757506
 100.68493151 101.84757506 101.84757506 101.84757506 126.
 123.52941176 102.08333333 102.7972028  102.55813953 103.52112676
 104.00943396 137.38317757 137.8125     138.67924528 139.11671924
 139.11671924 139.55696203 140.44585987 139.11671924 137.38317757
 136.53250774 135.27607362   0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.         134.45121951 134.45121951 134.45121951
 134.45121951 134.45121951 134.45121951 134.45121951 134.86238532
 135.27607362 156.93950178 162.13235294 166.41509434 170.27027027
 177.64892578 177.82258065 182.98755187 169.57397461 153.42407227
 137.27416992 127.40478516 125.61035156 123.81591797 123.81591797
 123.81591797 124.92917847 125.28409091 123.81591797 127.4566474
 128.19767442 128.57142857 128.57142857 128.94736842 155.28169014
 155.28169014 181.23779297 202.35133017 223.8845333  225.67896689
 226.09863281 226.09863281 183.75       183.75       177.64892578
 185.29411765 186.07594937 186.86440678 186.86440678 186.86440678
 177.64892578 177.64892578 177.64892578 177.64892578 177.64892578
 172.265625   165.08789062 157.91015625 154.32128906 148.93798828
 143.5546875  139.96582031 139.96582031 139.96582031 139.96582031
 139.96582031 139.96582031 132.78808594 125.61035156 115.7480315
 115.14360313 112.21374046 112.21374046 111.64556962 110.52631579
 110.52631579 110.52631579 109.15841584 109.15841584 108.08823529
 108.08823529 108.08823529 109.4292804  111.92893401 111.92893401
 111.92893401 111.92893401 111.08312343 110.25       110.25
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.          91.875
  92.25941423  92.25941423  92.45283019 138.24451411 138.24451411
 138.24451411 138.24451411 138.24451411 138.24451411 138.24451411
 137.8125     138.24451411 138.24451411   0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.        ]
In [38]:
file_target_pitch = YAAPT('fileTarget.wav')
print('pitch: ',file_target_pitch)
pitch:  [  0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.         141.34615385 139.11671924 134.86238532
 134.45121951 134.45121951 134.45121951 134.86238532 140.44585987
 143.18181818 137.8125     128.57142857 127.82608696 127.82608696
 130.08849558 127.82608696 128.57142857 128.19767442   0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.          83.84030418
  85.13513514  83.36483932  83.84030418  84.33837891  84.33837891
  86.1328125   88.2         86.1328125   88.73239437  88.73239437
  86.1328125   86.1328125   86.1328125   86.1328125   86.1328125
  86.1328125   86.1328125   86.1328125  100.48828125 118.76197525
 138.50074478 138.67924528 138.67924528 145.34912109 145.34912109
 145.34912109 145.34912109 145.34912109 141.80064309 141.80064309
 142.6574707  142.25806452 142.25806452 142.25806452 142.25806452
 142.25806452 141.80064309 141.80064309 141.80064309 141.80064309
 141.80064309 141.80064309 116.66666667 114.24870466 111.36363636
 100.22727273 100.22727273   0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.         129.3255132
 128.57142857 128.19767442 126.         125.64102564 124.92917847
 124.22535211 123.52941176 123.52941176 123.18435754 123.18435754
 121.82320442 123.18435754 124.57627119 124.92917847 126.
 126.36103152 126.36103152 126.36103152 126.36103152 127.08933718
 127.08933718 127.08933718 127.08933718 127.82608696 129.70588235
 129.3255132  128.19767442 128.57142857 128.57142857 128.57142857
 128.57142857 128.57142857 128.94736842 129.3255132  130.08849558
 130.08849558 129.3255132  129.70588235 129.70588235 129.3255132
 128.94736842 128.57142857 128.94736842 128.94736842 128.94736842
 128.94736842 128.19767442 127.4566474  127.4566474  128.57142857
 128.19767442 130.47337278 129.70588235 128.19767442 128.57142857
 128.94736842 129.3255132  129.70588235 128.57142857 128.57142857
 128.19767442 129.3255132  131.64179104 134.04255319 136.11111111
 137.38317757 138.24451411 142.25806452 142.25806452 143.64820847
 147.4916388  149.49152542 150.51194539 151.02739726 150.
 150.         148.48484848 147.4916388  143.64820847 141.34615385
 138.67924528 138.67924528 138.24451411 147.4916388  137.8125
 136.11111111 134.86238532 134.04255319 134.86238532 135.69230769
 134.04255319 134.04255319 134.04255319 134.04255319 134.86238532
 134.86238532 133.63636364 132.03592814 130.47337278 129.70588235
 128.94736842 129.70588235 130.47337278 130.47337278 130.47337278
 130.47337278 130.47337278 131.64179104 132.43243243 132.43243243
 134.04255319 135.27607362 136.53250774 138.24451411   0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.         136.11111111 135.69230769 136.11111111 136.11111111
 135.69230769 134.04255319 133.2326284  131.64179104 128.94736842
 128.94736842 125.64102564 125.64102564   0.           0.
   0.           0.         132.03592814 131.64179104 132.43243243
 131.25       131.25       134.86238532 136.53250774 138.24451411
 142.25806452 144.59016393 147.         148.98648649 150.51194539
 151.54639175 152.06896552 153.65853659 153.65853659 153.65853659
 153.65853659   0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.         135.27607362 133.63636364
 129.3255132  124.22535211   0.           0.           0.
   0.           0.           0.           0.         129.70588235
 131.25       129.70588235 127.4566474  124.22535211 122.84122563
 124.22535211 124.57627119 124.22535211 121.82320442 121.15384615
 124.57627119 121.48760331 121.48760331 122.84122563 124.22535211
 124.22535211 123.52941176 123.52941176 123.52941176 123.87640449
 123.52941176   0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.         125.28409091 124.92917847
 124.92917847 127.08933718 128.19767442 128.94736842 127.4566474
 124.57627119 125.64102564 127.08933718 127.08933718 128.57142857
 126.72413793 127.08933718 128.19767442 127.08933718 130.08849558
 129.3255132  130.86053412 127.4566474  127.08933718 126.72413793
 127.4566474  126.72413793 125.64102564 126.         124.92917847
 123.52941176 122.16066482 123.18435754 122.5        124.22535211
 126.36103152 126.         127.4566474  127.08933718 126.72413793
 127.08933718 128.57142857 127.82608696 127.08933718 128.94736842
 128.94736842 128.94736842 128.19767442 127.4566474  126.36103152
 126.         125.64102564 126.         126.         125.64102564
 125.64102564 125.64102564 125.64102564 125.64102564 126.
 126.         126.         126.         125.64102564 125.64102564
 125.28409091 125.64102564 127.4566474  128.19767442 127.82608696
 126.72413793 126.36103152 126.         125.28409091 126.36103152
 126.         127.4566474  125.64102564 125.64102564 124.22535211
 126.         127.82608696 128.19767442 127.4566474  128.19767442
 128.57142857 127.08933718 127.08933718 126.36103152 126.36103152
 126.         126.         127.4566474  127.4566474  130.86053412
 134.04255319 142.7184466  144.59016393 145.54455446 146.51162791
 148.48484848 148.48484848 148.48484848 148.48484848 148.48484848
 148.48484848 145.06578947 146.51162791 144.59016393 144.59016393
 144.59016393 149.49152542 149.49152542 150.51194539 152.06896552
 154.73684211 155.83038869 156.38297872 155.83038869 156.38297872
 157.5        159.20577617   0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.         182.23140496 182.23140496
 181.48148148 180.73770492 180.73770492 181.48148148 181.48148148
 180.73770492 180.         180.73770492 181.48148148 205.11627907
 182.23140496 185.29411765 185.29411765 190.0862069  192.57641921
 192.57641921   0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.         130.08849558 130.08849558
 130.08849558 130.08849558 130.08849558   0.           0.
   0.           0.           0.           0.           0.
   0.         141.80064309 141.80064309 141.80064309 141.80064309
 153.65853659 153.65853659 154.1958042  113.65979381 113.65979381
 129.19921875 114.84375    100.48828125  89.63414634  88.0239521
  84.33837891  82.54394531  93.63057325 118.5483871  118.5483871
 118.5483871  118.5483871  118.5483871  118.5483871  118.230563
 118.230563   118.230563   117.9144385  117.28723404 117.28723404
 117.28723404   0.           0.           0.           0.
   0.           0.           0.           0.           0.
 118.230563   118.230563   118.230563   118.230563   116.97612732
 116.97612732 116.97612732 116.97612732 129.70588235 129.70588235
 129.70588235 129.70588235 127.82608696 127.82608696 126.72413793
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.           0.
   0.           0.           0.           0.         105.50239234
 106.00961538 106.00961538 106.00961538 105.50239234 105.25059666
 106.00961538 106.00961538 105.50239234 105.25059666 105.
 105.25059666   0.           0.           0.           0.
   0.           0.           0.           0.           0.
 126.36103152 128.19767442 128.19767442 128.19767442 128.19767442
 128.19767442 130.86053412 148.04077148 148.93798828 142.7184466
 144.11764706 144.11764706 144.59016393 151.02739726 157.91015625
 161.49902344 161.49902344 161.49902344 161.49902344 161.49902344
 161.49902344 167.68060837 168.96551724 168.96551724 165.08789062
 170.93023256 172.265625   172.265625   172.265625   173.62204724
 175.69721116 175.69721116 175.69721116 174.3083004  174.3083004
 174.3083004  174.3083004  174.3083004  174.3083004    0.
   0.           0.           0.           0.           0.
   0.           0.         158.63309353 160.36363636 160.36363636
 160.36363636 160.36363636 160.36363636 163.33333333 163.94052045
 163.94052045 163.94052045 163.94052045 163.94052045 163.94052045
 163.94052045 165.16853933 165.16853933 166.41509434 165.16853933
 168.32061069 165.16853933 158.63309353 154.73684211 152.06896552
 150.         149.49152542 145.34912109 148.98648649 148.98648649
 148.98648649 149.49152542 149.49152542 151.02739726 151.02739726
 151.54639175 152.59515571 152.59515571 152.59515571 153.125
 153.125      153.125      153.125      151.54639175 150.
 152.59515571 152.06896552 151.54639175 151.54639175 152.06896552
 150.51194539 150.51194539 149.49152542 150.         147.
 140.89456869 139.55696203 132.8313253  130.47337278 130.86053412
 132.03592814 136.11111111 136.11111111 140.44585987 141.34615385
 145.06578947 147.         147.         146.51162791 149.49152542
 149.49152542 150.         150.         154.73684211 154.1958042
 156.38297872 164.55223881 159.20577617 159.20577617 159.20577617
 150.73242188 150.73242188 150.73242188 147.14355469   0.
 156.93950178   0.           0.           0.         142.25806452
 151.54639175 153.125      153.125      156.93950178 170.27027027
 170.27027027 170.27027027 172.94117647 172.94117647 173.62204724
 172.265625   172.265625   172.265625   172.265625   178.54251012
 178.54251012 179.26829268 180.73770492 181.48148148 182.23140496
 183.75       186.07594937 188.46153846 190.90909091 190.90909091
 190.90909091 244.04296875 242.24853516 242.24853516 236.86523438
   0.         190.20996094 172.265625   172.265625   172.265625
 172.265625   172.265625   174.06005859 183.03222656 192.00439453
 199.18212891 199.18212891 162.13235294 167.68060837 170.93023256
 170.93023256 170.93023256 168.96551724 168.96551724 167.68060837
 165.78947368 168.96551724 146.51162791 177.64892578 180.
 181.48148148 181.48148148 181.48148148 181.48148148   0.
   0.           0.           0.           0.           0.
   0.         129.3255132  133.2326284  134.45121951 136.53250774
 136.95652174 138.67924528 141.80064309 144.59016393 146.02649007
 147.98657718 148.48484848 150.         151.02739726 148.48484848
 153.125      151.54639175 152.59515571 152.06896552 153.65853659
 152.59515571 151.54639175 154.1958042  158.06451613 160.36363636
 162.73062731 163.94052045 165.16853933 167.68060837 169.61538462
 177.10843373 177.10843373 177.82258065 177.82258065 177.82258065
 177.82258065 177.82258065 176.4        174.3083004  174.3083004 ]

سیگنال صوت مبدا را به مقدار نسبت پیچ سیگنال مبدا به هدف (پیچش را شیفت میدهیم) پیچ میکنیم

In [39]:
for i in range(len(file_pitch)):
    f1 = False
    if file_pitch[i]!=0.0 :
        for k in range(8):
            if file_pitch[i+k]==0.0:
                f1=True
        if not(f1):
            for j in range(i+1,len(file_pitch)):
                if int(file_pitch[j])==0:
                    a = j-i
                    break
            break
        
for i in range(len(file_target_pitch)):
    f2 = False
    if file_target_pitch[i]!=0.0:
        for k in range(8):
            if file_target_pitch[i+k]==0.0:
                f2=True
        if not(f2):
            for j in range(i+1,len(file_target_pitch)):
                if int(file_target_pitch[j])==0:
                    b = j-i
                    break
            break
        

p = a/b
print(p)

IPython.display.Audio(DFT_pshift(data, p, ms2smp(40, rate), 0.1), rate=rate)
1.0
Out[39]:
In [43]:
RECORD_SECONDS_realtime = 3  # time of recording in seconds
CHUNK = 1024 # length of every chunk
WAVE_OUTPUT_FILENAME_realtime = "file_realtim.wav"  # file name

# real time is disabled because it doesn't get out of this loop unless with a keyboard interrupt
# and it generates an error showing that interupt
# if you want to run the realtime change the condition of while to "True" in the snippet below



while False:
    stream = audio.open(
        format=FORMAT,
        channels=CHANNELS,
        rate=RATE,
        input=True,
        frames_per_buffer=CHUNK
    )

    # start Recording

    frames = []
    print("recording...")
    for i in range(0, int(RATE / CHUNK * RECORD_SECONDS_realtime)):
        

        data_realtime = stream.read(CHUNK)
        
        frames.append(data_realtime)
    print("play...")


    # stop Recording
    stream.stop_stream()
    stream.close()

    # storing voice
    waveFile = wave.open(WAVE_OUTPUT_FILENAME_realtime, 'wb')
    waveFile.setnchannels(CHANNELS)
    waveFile.setsampwidth(audio.get_sample_size(FORMAT))
    waveFile.setframerate(RATE)
    waveFile.writeframes(b''.join(frames))
    waveFile.close()
    
    
    rate_realtime, data_realtime = wav.read('file_realtim.wav')
    out = DFT_pshift(data_realtime, p, ms2smp(40, rate_realtime), 0.1)
  
    write('out_realtime.wav', 44100, out)
    playsound('out_realtime.wav')
In [ ]: